// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
// This source file is part of the Cangjie project, licensed under Apache-2.0
// with Runtime Library Exception.
//
// See https://cangjie-lang.cn/pages/LICENSE for license information.













package std.unittest.common
import std.collection.ArrayList
import std.collection.HashMap
import std.collection.HashSet
import std.collection.concat
import std.collection.collectHashSet
import std.collection.filter
import std.collection.first

import std.collection.*
import std.convert.*
import std.sync.ReentrantMutex
import std.collection.enumerate

@!APILevel[since: "12", atomicservice : true]
public interface KeyFor<T> {
}

@!APILevel[since: "12", atomicservice : true]
public struct KeyTags <: KeyFor<Array<String>> {
    @!APILevel[since: "12", atomicservice : true]
    static public prop tags: KeyTags
    
    @!APILevel[since: "12", atomicservice : true]
    public prop name: String
}

@!APILevel[since: "12", atomicservice : true]
abstract sealed class ConfigurationKey <: Equatable<ConfigurationKey> & Hashable {
    @!APILevel[since: "12", atomicservice : true]
    public override func hashCode(): Int64
    
    @!APILevel[since: "12", atomicservice : true]
    public override operator func ==(that: ConfigurationKey): Bool
    
    @!APILevel[since: "12", atomicservice : true]
    public override operator func !=(that: ConfigurationKey): Bool
}

extend ConfigurationKey {
    @!APILevel[since: "12", atomicservice : true]
    public static func create<T>(name: String): ConfigurationKey
}

/**
* Configuration: the object that stores unittest configuration data produced by @Configure macro.
* Configuration is a HashMap-like class, but instead of key and value types, it always have keys of type String,
* and values of any given type
*/
@!APILevel[since: "12", atomicservice : true]
public class Configuration <: ToString {
    /**
    * Default constructor: construct an empty configuration
    */
    @!APILevel[since: "12", atomicservice : true]
    public init()
    
    /**
    * Try to get value of type `T` using key `key`
    * @param key the key to look up in the configuration
    * @param T the type of the value to look up in the configuration
    * @returns Some(value) where value has type T if this configuration object contains
    *          a value of type `T` at key `key`
    *          None if there is no value for key `key` or the value is not of type `T`
    *
    * `key: KeyFor<T>` is generated by `@UnittestOption` macro. For example,
    * key for option `zxc` can be used as `KeyZxc.zxc`.
    */
    @!APILevel[since: "12", atomicservice : true]
    public func get<T>(key: KeyFor<T>): ?T
    
    /**
    * Try to get value of type `T` using key `key`
    * @param key the key to look up in the configuration
    * @param T the type of the value to look up in the configuration
    * @returns Some(value) where value has type T if this configuration object contains
    *          a value of type `T` at key `key`
    *          None if there is no value for key `key` or the value is not of type `T`
    *
    */
    @!APILevel[since: "12", atomicservice : true]
    public func getByName<T>(name: String): ?T
    
    /**
    * Set the key `key` to value `value` in this configuration object for type `T`
    * @param key the key to look up in the configuration
    * @param value the value to put into the configuration by key `key`
    * @param T the type of the value
    * @returns Unit
    *
    * `key: KeyFor<T>` is generated by `@UnittestOption` macro. For example,
    * key for option `zxc` can be used as `KeyZxc.zxc`.
    */
    @!APILevel[since: "12", atomicservice : true]
    public func set<T>(key: KeyFor<T>, value: T): Unit
    
    /**
    * Set the key `key` to value `value` in this configuration object for type `T`
    * @param key the key to look up in the configuration
    * @param value the value to put into the configuration by key `key`
    * @param T the type of the value
    * @returns Unit
    */
    @!APILevel[since: "12", atomicservice : true]
    public func setByName<T>(name: String, value: T): Unit
    
    /**
    * Remove the key `key` in this configuration object for type `T`
    * Does not remove other v
    * @param key the key to look up in the configuration
    * @param T the type of the value
    * @returns Some(v) holding existing value if this key with this type is in the configuration
    *          None otherwise
    *
    * `key: KeyFor<T>` is generated by `@UnittestOption` macro. For example,
    * key for option `zxc` can be used as `KeyZxc.zxc`.
    */
    @!APILevel[since: "12", atomicservice : true]
    public func remove<T>(key: KeyFor<T>): ?T
    
    /**
    * Remove the key `key` in this configuration object for type `T`
    * Does not remove other v
    * @param key the key to look up in the configuration
    * @param T the type of the value
    * @returns Some(v) holding existing value if this key with this type is in the configuration
    None otherwise
    */
    @!APILevel[since: "12", atomicservice : true]
    public func removeByName<T>(key: String): ?T
    
    /**
    * Clone this configuration object
    * @returns new Configuration object with the same keys and values as this one
    */
    @!APILevel[since: "12", atomicservice : true]
    public func clone(): Configuration
    
    /**
    * Printable representation of this configuration object
    * For entries that implement ToString, uses it
    * For entries that do not implement ToString, displays '<value not printable>'
    */
    @!APILevel[since: "12", atomicservice : true]
    public func toString(): String
    
    // child has priority over values in parent
    @!APILevel[since: "12", atomicservice : true]
    public static func merge(parent: Configuration, child: Configuration): Configuration
}

/**
* Component of the DataStrategy that is used to provide data to test
* @param T the type of the data this provider provides
*/
@!APILevel[since: "12", atomicservice : true]
public interface DataProvider<T> {
}

/**
* Component of the DataStrategy that is used to reduce the data during testing
* @param T the type of the data this shrinker handles
*/
@!APILevel[since: "12", atomicservice : true]
public interface DataShrinker<T> {
}

/**
* A strategy that provides data to a parameterized test
* @param T the type of the data this strategy operates on
*/
@!APILevel[since: "12", atomicservice : true]
public interface DataStrategy<T> {
}

/**
* The implementation of DataStrategy interface for Array
* Is needed to allow tests in the form
* ```
* @Test[x in [1,2,3]]
* func test(x: Int64) {}
* ```
*/
@!APILevel[since: "12", atomicservice : true]
extend<T> Array<T> <: DataStrategy<T> & DataProvider<T> {
    /**
    * Get the provided data from the provider
    * @return this
    */
    @!APILevel[since: "12", atomicservice : true]
    public func provide(): Iterable<T>
    
    /**
    * Is this provider infinite?
    * @returns false
    */
    @!APILevel[since: "12", atomicservice : true]
    public prop isInfinite: Bool
    
    /**
    * Get the provider using the configuration object. Does not actually use any configuration.
    * @return this
    */
    @!APILevel[since: "12", atomicservice : true]
    public func provider(_: Configuration): DataProvider<T>
}

/**
* The implementation of DataStrategy interface for Range
* Is needed to allow tests in the form
* ```
* @Test[x in (0..5)]
* func test(x: Int64) {}
* ```
*/
@!APILevel[since: "12", atomicservice : true]
extend<T> Range<T> <: DataStrategy<T> & DataProvider<T> {
    /**
    * Get the provided data from the provider
    * @return this
    */
    @!APILevel[since: "12", atomicservice : true]
    public func provide(): Iterable<T>
    
    /**
    * Is this provider infinite?
    * @returns false
    */
    @!APILevel[since: "12", atomicservice : true]
    public prop isInfinite: Bool
    
    /**
    * Get the provider using the configuration object. Does not actually use any configuration.
    * @return this
    */
    @!APILevel[since: "12", atomicservice : true]
    public func provider(_: Configuration): DataProvider<T>
}

/**
* Extended DataModel to add func toJson() and func fromJson().
*/
extend DataModel <: ToJson {
    /**
    * Parses JsonValue data into DataModel.
    *
    * @param jv JsonValue in JSON data format.
    * @return parsed DataModel.
    *
    * @since 0.17.4
    *
    * @throws JsonException if jv cannot be converted to DataModel.
    */
    @!APILevel[since: "12", atomicservice : true]
    public static func fromJson(jv: JsonValue): DataModel
    
    /**
    * Convert DataModel to JsonValue.
    *
    * @return json-converted JsonValue.
    *
    * @since 0.20.2
    *
    * @throws JsonException if DataModel cannot be converted to JsonValue.
    */
    @!APILevel[since: "12", atomicservice : true]
    public func toJson(): JsonValue
}

@!APILevel[since: "12", atomicservice : true]
public class UnittestOptionValidationException <: Exception {
}

@!APILevel[since: "12", atomicservice : true]
public enum OptionValidity {
    @!APILevel[since: "12", atomicservice : true]
    UnknownOptionType |
    @!APILevel[since: "12", atomicservice : true]
    InvalidOption(String) |
    @!APILevel[since: "12", atomicservice : true]
    ValidOption(ConfigurationKey)
}

type Validator = (Any) -> OptionValidity
@!APILevel[since: "12", atomicservice : true]
public var unittestOptionsRegistryClosed = false

@!APILevel[since: "12", atomicservice : true]
public struct OptionInfo {
}

@!APILevel[since: "12", atomicservice : true]
public let optionsInfo: HashMap<String, OptionInfo> = HashMap()

@!APILevel[since: "12", atomicservice : true]
public func registerOptionValidator(name: String, validator: Validator): Unit

@!APILevel[since: "12", atomicservice : true]
public func setOptionInfo(
    name: String,
    types: Array<String>,
    description!: ?String = None
): Unit

@!APILevel[since: "12", atomicservice : true]
public func setOrUpdateOptionInfo(
    name: String,
    description: ?String,
    ty: String,
    typeDescription: String
): Unit

/**
* Color of the pretty output for tests
*/
@!APILevel[since: "12", atomicservice : true]
public enum Color <: Equatable<Color> {
    @!APILevel[since: "12", atomicservice : true]
    RED |
    @!APILevel[since: "12", atomicservice : true]
    GREEN |
    @!APILevel[since: "12", atomicservice : true]
    YELLOW |
    @!APILevel[since: "12", atomicservice : true]
    BLUE |
    @!APILevel[since: "12", atomicservice : true]
    CYAN |
    @!APILevel[since: "12", atomicservice : true]
    MAGENTA |
    @!APILevel[since: "12", atomicservice : true]
    GRAY |
    @!APILevel[since: "12", atomicservice : true]
    DEFAULT_COLOR
    @!APILevel[since: "12", atomicservice : true]
    public operator func ==(that: Color): Bool
    
    @!APILevel[since: "12", atomicservice : true]
    public operator func !=(that: Color)
}

/**
* Abstract class to print your output to with support for indentation, alignment and colors
*/
@!APILevel[since: "12", atomicservice : true]
public abstract class PrettyPrinter {
    /**
    * PrettyPrinter constructor
    * @param indentationSize the size (in spaces) of a single indentation
    * @param startingIndent the initial number of indentations applied
    */
    @!APILevel[since: "12", atomicservice : true]
    public PrettyPrinter(let indentationSize!: UInt64 = 4, let startingIndent!: UInt64 = 0)
    
    /**
    * Is this pretty-printer on the top level of indentation?
    * @return false if current indent is not empty
    */
    @!APILevel[since: "12", atomicservice : true]
    public prop isTopLevel: Bool
    
    /**
    * Run a block of code with indentation
    * Typical usage:
    pp.indent {
    pp.appendLine("1")
    pp.appendLine("2")
    pp.appendLine("3")
    }
    * This outputs three lines with "1", "2" and "3", all indented one indentation
    * level more than current indentation
    * @param body the code block to run with indentation
    */
    @!APILevel[since: "12", atomicservice : true]
    public func indent(body: () -> Unit): PrettyPrinter
    
    /**
    * Run a block of code with indentation
    * Typical usage:
    pp.indent(2) {
    pp.appendLine("1")
    pp.appendLine("2")
    pp.appendLine("3")
    }
    * This outputs three lines with "1", "2" and "3", all indented 2 indentation
    * levels more than current indentation
    * @param symbols the number of indentations to indent
    * @param body the code block to run with indentation
    */
    @!APILevel[since: "12", atomicservice : true]
    public func indent(indents: UInt64, body: () -> Unit): PrettyPrinter
    
    /**
    * Run a block of code with fully custom indentation in addition to the current level
    * Typical usage:
    pp.customOffset(5) {
    pp.appendLine("1")
    pp.appendLine("2")
    pp.appendLine("3")
    }
    * This outputs three lines with "1", "2" and "3", all indented by exactly 5 spaces
    * more than current indentation
    *
    * This should only be used when fully custom (not representable in indentation offsets)
    * offset is needed, in all other cases use indent()
    * @param symbols the number of spaces to indent
    * @param body the code block to run with indentation
    */
    @!APILevel[since: "12", atomicservice : true]
    public func customOffset(symbols: UInt64, body: () -> Unit): PrettyPrinter
    
    /**
    * Run a block of code with a different color
    * Typical usage:
    pp.colored(RED) {
    pp.appendLine("1")
    pp.appendLine("2")
    pp.appendLine("3")
    }
    * This outputs three lines with "1", "2" and "3", all in red color
    *
    * @param color the color to use
    * @param body the code block to run with color
    */
    @!APILevel[since: "12", atomicservice : true]
    public func colored(color: Color, body: () -> Unit): PrettyPrinter
    
    /**
    * Run a block of code. And if such behavior is supported by corresponding PrettyPrinter 
    * whatever is printed inside this block of code will be 
    * fitted into a space that corresponds to a space taken by `spaceSize` halfwidth characters.
    *
    * @param spaceSize size of the space output must fit into
    * @param body the code block to run with color
    */
    @!APILevel[since: "12", atomicservice : true]
    public open func fillLimitedSpace(spaceSize: Int64, body: () -> Unit): PrettyPrinter
    
    /**
    * Print a string with a different color
    * @param color the color to use
    * @param string the string to print
    */
    @!APILevel[since: "12", atomicservice : true]
    public func colored(color: Color, text: String): PrettyPrinter
    
    /**
    * Append a string to this pretty printer
    * Note: this does not support multiline strings, no indentation is provided for that case
    * @param value the string to print
    */
    @!APILevel[since: "12", atomicservice : true]
    public func append(text: String): PrettyPrinter
    
    /**
    * Append a string to this pretty printer, aligned in the space of `size` characters, centered
    * Note: this does not support multiline strings, no indentation is provided for that case
    * @param assert the string to print
    * @param size the size of the box to use
    */
    @!APILevel[since: "12", atomicservice : true]
    public func appendCentered(text: String, space: UInt64): PrettyPrinter
    
    @!APILevel[since: "12", atomicservice : true]
    public func appendLeftAligned(text: String, space: UInt64): PrettyPrinter
    
    @!APILevel[since: "12", atomicservice : true]
    public func appendRightAligned(text: String, space: UInt64): PrettyPrinter
    
    /**
    * Append a PrettyPrintable value to this pretty printer
    * @param value the value to print
    */
    @!APILevel[since: "12", atomicservice : true]
    public func append<PP>(value: PP): PrettyPrinter where PP <: PrettyPrintable
    
    /**
    * Print a newline
    */
    @!APILevel[since: "12", atomicservice : true]
    public func newLine(): PrettyPrinter
    
    /**
    * Print a given string, followed by a newline
    * @param value the string to print
    */
    @!APILevel[since: "12", atomicservice : true]
    public func appendLine(text: String): PrettyPrinter
    
    /**
    * Print a given PrettyPrintable value, followed by a newline
    * @param value the value to print
    */
    @!APILevel[since: "12", atomicservice : true]
    public func appendLine<PP>(value: PP): PrettyPrinter where PP <: PrettyPrintable
}

/**
* A builder-like class to store pretty-printed output.
* Main usage is for intermediate storage and passing of such values.
* Implements both PrettyPrinter (can be printed to) and PrettyPrintable (can be printed from)
*/
@!APILevel[since: "12", atomicservice : true]
public class PrettyText <: PrettyPrinter & PrettyPrintable & ToString {
    /**
    * Default constructor: makes an empty PrettyText
    */
    @!APILevel[since: "12", atomicservice : true]
    public init()
    
    /**
    * String-based constructor: makes a PrettyText with starting content of `string`
    */
    @!APILevel[since: "12", atomicservice : true]
    public init(string: String)
    
    /**
    * Utility factory function: create a PrettyText from a PrettyPrintable by printing it.
    * This is static only because generic constructors are not allowed.
    */
    @!APILevel[since: "12", atomicservice : true]
    public static func of<PP>(pp: PP): PrettyText where PP <: PrettyPrintable
    
    /**
    * @return true if nothing has been put into this object yet, false otherwise
    */
    @!APILevel[since: "12", atomicservice : true]
    public func isEmpty(): Bool
    
    /**
    * Print this PrettyText into a pretty printer: output should look exactly like input
    * @param to the pretty printer to print to
    */
    @!APILevel[since: "12", atomicservice : true]
    public func pprint(to: PrettyPrinter): PrettyPrinter
    
    /**
    * Print this PrettyText to a String: output should look exactly like it would on an output printer,
    * but without colors
    */
    @!APILevel[since: "12", atomicservice : true]
    public func toString(): String
}

/**
* Pretty printable: interface signifying this type can be pretty-printed
*/
@!APILevel[since: "12", atomicservice : true]
public interface PrettyPrintable {
}

/**
* Pretty printable instance for Array: print elements in succession
*/
extend<T> Array<T> <: PrettyPrintable where T <: PrettyPrintable {
    @!APILevel[since: "12", atomicservice : true]
    public func pprint(to: PrettyPrinter): PrettyPrinter
}

/**
* Pretty printable instance for ArrayList: print elements in succession
*/
extend<T> ArrayList<T> <: PrettyPrintable where T <: PrettyPrintable {
    @!APILevel[since: "12", atomicservice : true]
    public func pprint(to: PrettyPrinter): PrettyPrinter
}

extend Color <: Serializable<Color> {
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    @!APILevel[since: "12", atomicservice : true]
    public static func deserialize(dm: DataModel): Color
}

extend PrettyPrintableTextChunk <: Serializable<PrettyPrintableTextChunk> {
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    @!APILevel[since: "12", atomicservice : true]
    public static func deserialize(dm: DataModel): PrettyPrintableTextChunk
}

extend PrettyText <: Serializable<PrettyText> {
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    @!APILevel[since: "12", atomicservice : true]
    public static func deserialize(dm: DataModel): PrettyText
}

/**
* Extended Int64 to implement Serializable.
*/
extend Int64 <: Serializable<Int64> {
    /**
    * Serializes Int64 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Int64.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Int64.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Int64
}

/**
* Extended Int32 to implement Serializable.
*/
extend Int32 <: Serializable<Int32> {
    /**
    * Serializes Int32 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Int32.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Int32.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Int32
}

/**
* Extended Int16 to implement Serializable.
*/
extend Int16 <: Serializable<Int16> {
    /**
    * Serializes Int16 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Int16.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Int16.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Int16
}

/**
* Extended Int8 to implement Serializable.
*/
extend Int8 <: Serializable<Int8> {
    /**
    * Serializes Int8 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Int8.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Int8.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Int8
}

/**
* Extended UInt64 to implement Serializable.
*/
extend UInt64 <: Serializable<UInt64> {
    /**
    * Serializes UInt64 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into UInt64.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized UInt64.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): UInt64
}

/**
* Extended UInt32 to implement Serializable.
*/
extend UInt32 <: Serializable<UInt32> {
    /**
    * Serializes UInt32 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into UInt32.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized UInt32.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): UInt32
}

/**
* Extended UInt16 to implement Serializable.
*/
extend UInt16 <: Serializable<UInt16> {
    /**
    * Serializes UInt16 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into UInt16.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized UInt16.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): UInt16
}

/**
* Extended UInt8 to implement Serializable.
*/
extend UInt8 <: Serializable<UInt8> {
    /**
    * Serializes UInt8 into DataModelInt.
    *
    * @return serialized DataModelInt.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into UInt8.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized UInt8.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if dm is not DataModelnt
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): UInt8
}

/**
* Extended Float64 to implement Serializable.
*/
extend Float64 <: Serializable<Float64> {
    /**
    * Serializes Float64 into DataModelFloat.
    *
    * @return serialized DataModelFloat.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Float64.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Float64.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if data is not DataModelFloat
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Float64
}

/**
* Extended Float32 to implement Serializable.
*/
extend Float32 <: Serializable<Float32> {
    /**
    * Serializes Float32 into DataModelFloat.
    *
    * @return serialized DataModelFloat.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Float32.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Float32.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if data is not DataModelFloat
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Float32
}

/**
* Extended Float16 to implement Serializable.
*/
extend Float16 <: Serializable<Float16> {
    /**
    * Serializes Float16 into DataModelFloat.
    *
    * @return serialized DataModelFloat.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Float16.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Float16.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if data is not DataModelFloat
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Float16
}

/**
* Extended Bool to implement Serializable.
*/
extend Bool <: Serializable<Bool> {
    /**
    * Serializes Bool into DataModelBool.
    *
    * @return serialized DataModelBool.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Bool.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Bool.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if data is not DataModelBool
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Bool
}

/**
* Extended String to implement Serializable.
*/
extend String <: Serializable<String> {
    /**
    * Serializes String into DataModelString.
    *
    * @return serialized DataModelString.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into String.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized String.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if data is not DataModelString
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): String
}

/**
* Extended Rune to implement Serializable.
*/
extend Rune <: Serializable<Rune> {
    /**
    * Serializes Rune into DataModelString.
    *
    * @return serialized DataModelString.
    *
    * @since 0.17.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Rune.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Rune.
    *
    * @since 0.17.4
    *
    * @throws DataModelException if data is not DataModelString
    * @throws Exception if data is not Rune
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Rune
}

/**
* Extended Option to implement Serializable.
*/
extend<T> Option<T> <: Serializable<Option<T>> where T <: Serializable<T> {
    /**
    * Serializes Option into DataModel of T.
    *
    * @return serialized DataModel.
    *
    * @since 0.18.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Option.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Option.
    *
    * @since 0.18.4
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Option<T>
}

/**
* Extended Array to implement Serializable.
*/
extend<T> Array<T> <: Serializable<Array<T>> where T <: Serializable<T> {
    /**
    * Serializes Array into DataModelSeq.
    *
    * @return serialized DataModelSeq.
    *
    * @since 0.29.3
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into Array.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized Array.
    *
    * @since 0.29.3
    *
    * @throws DataModelException if data is not DataModelSeq
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): Array<T>
}

/**
* Extended ArrayList to implement Serializable.
*/
extend<T> ArrayList<T> <: Serializable<ArrayList<T>> where T <: Serializable<T> {
    /**
    * Serializes ArrayList into DataModelSeq.
    *
    * @return serialized DataModelSeq.
    *
    * @since 0.22.4
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /**
    * Deserializing DataModel into ArrayList.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized ArrayList.
    *
    * @since 0.22.4
    *
    * @throws DataModelException if data is not DataModelSeq
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): ArrayList<T>
}

/**
* Extended HashSet to implement Serializable.
*/
extend<T> HashSet<T> <: Serializable<HashSet<T>> where T <: Serializable<T> & Hashable & Equatable<T> {
    /*
    * Serializes HashSet into DataModelSeq.
    *
    * @return serialized DataModelSeq.
    *
    * @since 0.23.3
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /*
    * Deserializing DataModel into HashSet.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized HashSet.
    *
    * @since 0.23.3
    *
    * @throws DataModelException if data is not DataModelSeq
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): HashSet<T>
}

/**
* Extended HashMap to implement Serializable.
*/
extend<K, V> HashMap<K, V> <: Serializable<HashMap<K, V>>
    where K <: Serializable<K> & Hashable & Equatable<K>, V <: Serializable<V> {
    /*
    * Serializes HashMap into DataModelStruct.
    *
    * @return serialized DataModelStruct.
    *
    * @since 0.23.3
    *
    * @throws DataModelException if the type of key of this hashmap is not String
    */
    @!APILevel[since: "12", atomicservice : true]
    public func serializeInternal(): DataModel
    
    /*
    * Deserializing DataModel into HashMap.
    *
    * @param dm DataModel to be deserialized.
    * @return deserialized HashMap.
    *
    * @since 0.23.3
    *
    * @throws DataModelException if dm is not DataModelStruct type or the field of dm is not String type
    */
    @!APILevel[since: "12", atomicservice : true]
    static public func deserialize(dm: DataModel): HashMap<K, V>
}

extend Rune <: TextWidth {
    @!APILevel[since: "12", atomicservice : true]
    public func width(): Int64
}

extend String <: TextWidth {
    @!APILevel[since: "12", atomicservice : true]
    public func width(): Int64
}

